package gitlabapi

import (
	"encoding/json"
	"fmt"
	"github.com/sirupsen/logrus"
	"gitlab-sync/config"
	"gitlab-sync/util"
)

type Group struct {
	Id                        int    `json:"id"`
	Name                      string `json:"name"`
	Path                      string `json:"path"`
	Description               string `json:"description"`
	Parent_id                 int    `json:"parent_id"`
	Visibility                string `json:"visibility"`
	Project_creation_level    string `json:"project_creation_level"`
	Auto_devops_enabled       bool   `json:"auto_devops_enabled"`
	Subgroup_creation_level   string `json:"subgroup_creation_level"`
	Default_branch_protection int    `json:"default_branch_protection"`
	Request_access_enabled    bool   `json:"request_access_enabled"`
	Full_name                 string `json:"full_name"`
	Full_path                 string `json:"full_path"`
}

type SugGroup struct {
	Id            int    `json:"id"`
	Subgroup_name string `json:"name"`
	Subgroup_path string `json:"path"`
	Description   string `json:"description"`
	Parent_id     int    `json:"parent_id"`
}

// 获取所有组
func CreateGroups(search string) []Group {
	logrus.Print("开始同步groups")
	var result []Group
	var page = 1
	parend_id := getNewGitParentId()
	//循环获取分组，直到没有数据
	for page > 0 {
		url := fmt.Sprintf(config.GetConfig().Gitlab.OriginRemoteUrl+config.GetConfig().Gitlab.GroupsApi+"?private_token="+config.GetConfig().OriginGitlab.PrivateToken+"&page=%d", page)
		if search != "all" {
			logrus.Printf("获取group：[%s]的信息:", search)
			url = fmt.Sprintf(url+"&search=%s", search)
		} else {
			logrus.Printf("查询第[%d]页的groups信息:", page)
		}
		body := util.Get(url, config.GetConfig().Log.RequestLog)
		var group []Group
		err := json.Unmarshal(body, &group)
		if err != nil {
			logrus.Error("Error:%s", err)
			return nil
		}
		if len(group) == 0 {
			logrus.Printf("--------------[end]---------------")
			break
		}
		var i = 1
		for _, group := range group {
			logrus.Printf("执行第[%d]个,group[%s],description[%s]", i, group.Name, group.Description)
			group2,isExsit := GetGroupByName(group.Name)
			if !isNil(group2) && group2.Id != 0 && isExsit {
				logrus.Warn("目标仓库已存在相同的组，请先删除目标仓库的组再进行迁移！")
				continue
			}
			group.Parent_id = parend_id
			bytesData, _ := json.Marshal(group)
			newId := executeCreateGroup(bytesData, group.Path)
			CreateMembers(group.Id, newId, true)
			//getSubProjects(group.Id, new_group_id, config)
			i++
		}
		page++
		if search != "all" {
			page = 0
		}
		result = append(result, group...)
	}
	logrus.Println("同步groups结束")
	return result
}

// 获取子项目
func getSubProjects(id int, new_group_id int) {
	logrus.Println("get sub projects .....")
	url := fmt.Sprintf(config.GetConfig().Gitlab.OriginRemoteUrl+config.GetConfig().Gitlab.GroupsApi+"/%d/projects", id)
	logrus.Println("api:" + url)
	body := util.Get2(url, config.GetConfig().OriginGitlab.PrivateToken, config.GetConfig().Log.RequestLog)
	var group []Group
	err := json.Unmarshal(body, &group)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	for _, group := range group {
		logrus.Printf("project[%s],description[%s]", group.Name, group.Description)
		sugGroup := SugGroup{Subgroup_name: group.Name, Subgroup_path: group.Path, Description: group.Description, Parent_id: new_group_id}
		bytesData, _ := json.Marshal(sugGroup)
		_ = executeCreateGroup(bytesData, group.Path)
		//getSubProjects(group.Id,new_group_id,config)
	}
}

// 获取目标仓库的父节点编号
func getNewGitParentId() int {
	logrus.Printf("根据配置的父节点[%s]", config.GetConfig().TargetGitlab.ParentGroup)
	url := fmt.Sprintf(config.GetConfig().Gitlab.TargetRemoteUrl + config.GetConfig().Gitlab.GroupsApi + "?private_token=" + config.GetConfig().TargetGitlab.PrivateToken)
	body := util.Get(url, config.GetConfig().Log.RequestLog)
	var group []Group
	err := json.Unmarshal(body, &group)
	if err != nil {
		logrus.Error("Error:%s", err)
		return 0
	}
	var parent_id = 0
	for _, group := range group {
		if group.Name == config.GetConfig().TargetGitlab.ParentGroup {
			parent_id = group.Id
			break
		}
	}
	if parent_id == 0 {
		logrus.Printf("目标仓库不存在 [%s]，请手动创建", config.GetConfig().TargetGitlab.ParentGroup)
		return 0
	}
	logrus.Printf("查询parent_id值:%d", parent_id)
	return parent_id
}

// 创建分组
func executeCreateGroup(data []byte, name string) (id int) {
	logrus.Printf("执行同步")
	url := fmt.Sprintf(config.GetConfig().Gitlab.TargetRemoteUrl + config.GetConfig().Gitlab.GroupsApi)
	body := util.Post(url, data, config.GetConfig().TargetGitlab.PrivateToken, config.GetConfig().Log.RequestLog)
	//解析相应结果，获取ID
	var group Group
	err := json.Unmarshal(body, &group)
	if err != nil {
		logrus.Error("Error:%s", err)
		return 0
	}
	if group.Id == 0 {
		group,_ = GetGroupByName(name)
	}
	logrus.Printf("同步完成,groupid=[%d]", group.Id)
	return group.Id
}

func isNil(obj interface{}) bool {
	return obj == nil
}

// 通过项目名称获取新工程上的项目信息
func GetGroupByName(name string) (group Group,isExsit bool) {
	logrus.Printf("根据[%s]查询目标仓库中的信息", name)
	//循环获取分组，直到没有数据
	url := fmt.Sprintf(config.GetConfig().Gitlab.TargetRemoteUrl + config.GetConfig().Gitlab.GroupsApi + "?private_token=" + config.GetConfig().TargetGitlab.PrivateToken + "&search=" + name)
	body := util.Get(url, config.GetConfig().Log.RequestLog)
	var result []Group
	err := json.Unmarshal(body, &result)
	if err != nil {
		logrus.Error("Error:", err)
		return
	}
	if len(result) == 0 {
		return
	} else {
		isExsit=false
		for _,e := range result {
			if e.Name==name{
				isExsit=true
				break
			}
		}
		return result[0],isExsit
	}
}
